package edu.umd.ion.wavemeter.client;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.VerticalPanel;

import edu.umd.ion.wavemeter.service.ChannelInfo;
import edu.umd.ion.wavemeter.service.ChannelRoutingInfo;
import edu.umd.ion.wavemeter.service.WavemeterServiceAsync;

public class ChannelRoutingWidget extends Composite implements
		BeforeSelectionHandler<Integer> {
	private WavemeterServiceAsync WavemeterService;
	private HTML ChannelRoutingHTML, ChannelInfoHTML;
	private VerticalPanel Vertical;
	private Panel ErrorPanel;
	private Button Refresh;
	private HTML ErrorMessage;

	private native void reload() /*-{
    $wnd.location.reload();
   }-*/;


	private AsyncCallback<ChannelRoutingInfo[]> ChannelRoutingCallback = 
			new AsyncCallback<ChannelRoutingInfo[]>() {
		public void onFailure(Throwable caught) {
			try {
				ErrorMessage.setHTML("Command: " + caught.getMessage());
				throw caught;
			} catch (IncompatibleRemoteServiceException e) {
				// this client is not compatible with the server; cleanup and refresh the 
				// browser
				reload();
			} catch (Throwable e) {
				// last resort -- a very unexpected exception
			}
		}

		public void onSuccess(ChannelRoutingInfo[] result) {
			ErrorMessage.setHTML("");
			showChannelRouting(result);
		}
	};

	private AsyncCallback<ChannelInfo[]> ChannelInfoCallback = 
		new AsyncCallback<ChannelInfo[]>() {
	public void onFailure(Throwable caught) {
		try {
			ErrorMessage.setHTML("Command: " + caught.getMessage());
			throw caught;
		} catch (IncompatibleRemoteServiceException e) {
			// this client is not compatible with the server; cleanup and refresh the 
			// browser
			reload();
		} catch (Throwable e) {
			// last resort -- a very unexpected exception
		}
	}

	public void onSuccess(ChannelInfo[] result) {
		ErrorMessage.setHTML("");
		showChannelInfo(result);
	}
};
	
	public void showChannelRouting(ChannelRoutingInfo[] result) {
		if (result!=null) {
			String MessageHTML = new String("<h2>Channel routing table</h2><table border='1'><tr><td>Raw Channel</td><td>Virt Channel</td><td>Exposure</td><td>Names</td><td>Locked</td></tr>");
			for (int i=0; i<result.length; ++i) {
				ChannelRoutingInfo R = result[i];
				MessageHTML += "<tr><td>" + R.RawChannel + "</td><td>" + R.VirtChannel + "</td><td>" 
				+ R.Exposure + "</td><td>" + R.Name + "</td><td>" + R.LockEngaged + "</td></tr>";
			}
			MessageHTML += "</table>";
			ChannelRoutingHTML.setHTML(MessageHTML);
		}
	}

	public void showChannelInfo(ChannelInfo[] result) {
		if (result!=null) {
			String MessageHTML = new String("<h2>All known channels</h2><table border='1'><tr><td>Channel</td><td>Name</td><td>Last Activate</td></tr>");
			for (int i=0; i<result.length; ++i) {
				ChannelInfo R = result[i];
				MessageHTML += "<tr><td>" + R.Channel + "</td><td>" + R.Name + "</td><td>" 
				+ R.LastSeen + "</td></tr>";
			}
			MessageHTML += "</table>";
			ChannelInfoHTML.setHTML(MessageHTML);
		}
	}
	
	public void queryChannelRouting() {
		WavemeterService.channelRouting(ChannelRoutingCallback);
		WavemeterService.channelInfo(ChannelInfoCallback);
	}
	
	public ChannelRoutingWidget(WavemeterServiceAsync cb, Panel errorPanel ) {
		WavemeterService = cb;
		ErrorPanel = errorPanel;
		
		Refresh = new Button("Refresh",new ClickHandler() {
			public void onClick(ClickEvent event) {
				queryChannelRouting();
			}});
		ChannelRoutingHTML = new HTML();
		ChannelInfoHTML = new HTML();
		
		ErrorMessage = new HTML();
		ErrorPanel.add(ErrorMessage);
		
		Vertical = new VerticalPanel();
		Vertical.add(Refresh);
		Vertical.add(ChannelRoutingHTML);
		Vertical.add(ChannelInfoHTML);
		initWidget(Vertical);
		queryChannelRouting();
	}

	@Override
	public void onBeforeSelection(BeforeSelectionEvent<Integer> event) {
		queryChannelRouting(); 
	}
}
